﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace Centny
{
    public class ExtThickness
    {
        public Thickness BorderThickness { get; set; }
    }
    public partial class ExtButton : UserControl
    {
        public enum ButtonState
        {
            All = 1, Normal, PointerOver, Disabled, Pressed
        }
        public ExtButton()
        {
            this.InitializeComponent();
            Brush fbrush = Application.Current.Resources["ApplicationForegroundThemeBrush"] as Brush;
            this.SetForeground(fbrush);
            this.DataContext = this;
            this.StyleName = "Deafult";
            this.ContentTemplate = this.NormaltTemplate;
            this.Btn.Loaded += OnLoaded;
            this.Btn.Unloaded += OnUnLoaded;
        }
        public Visibility Visibility
        {
            get
            {
                return base.Visibility;
            }
            set
            {
                base.Visibility = value;
                this.Reload();
            }
        }
        private async void Reload()
        {
            await Task.Delay(10);
            this.OnLoaded(null, null);
        }
        public void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (this.Visibility.Equals(Visibility.Collapsed))
            {
                return;
            }
            this._BBorder = this.Child("BBorder") as Border;
            this.SetStyle(this.StyleName);
            this.SetTemplate(this.TempPath);
            this.IsEnabled = true;
        }
        private void OnUnLoaded(object sender, RoutedEventArgs e)
        {
            this.IsEnabled = false;
        }
        public void SetStyle(String name = "Default")
        {
            if (!this.ResSet.ContainsKey(name))
            {
                return;
            }
            ResourceDictionary rd = this.ResSet[name] as ResourceDictionary;
            if (rd == null)
            {
                return;
            }
            foreach (String k in rd.Keys)
            {

                Object obj = rd[k];
                if (obj is ResourceDictionary)
                {
                    this.SetVal(k, obj as ResourceDictionary);
                }
            }
            this.UpdateState(this.CurrentState);
        }
        public void SetTemplate(String tpath)
        {
            DataTemplate dt = this.GetTemplate(tpath);
            if (dt != null)
            {
                this.ContentTemplate = dt;
            }
            if (this.ContentTemplate != null)
            {
                FrameworkElement ui = this.ContentTemplate.LoadContent() as FrameworkElement;
                if (this.ActualHeight > 0)
                {
                    ui.Height = this.ActualHeight;
                }
                if (this.ActualWidth > 0)
                {
                    ui.Width = this.ActualWidth;
                }
                ui.DataContext = this;
                this.BBorder.Child = ui;
            }
        }
        /// <summary>
        /// set the template.
        /// </summary>
        /// <param name="tpath">the template path</param>
        public DataTemplate GetTemplate(String tpath)
        {
            if (tpath == null)
            {
                return null;
            }
            String[] ts = tpath.Split('.');
            String sname = "";
            String tname = "";
            if (ts.Length > 1)
            {
                sname = ts[0];
                tname = ts[1];
            }
            else
            {
                tname = ts[0];
            }
            DataTemplate dt = null;
            ResourceDictionary rd = null;
            if (sname == null || sname.Length < 1)
            {
                rd = this.ResSet;
            }
            else
            {
                if (!this.ResSet.ContainsKey(sname))
                {
                    return null;
                }
                rd = this.ResSet[sname] as ResourceDictionary;
            }
            if (rd == null)
            {
                return null;
            }
            if (!rd.ContainsKey(tname))
            {
                return null;
            }
            dt = rd[tname] as DataTemplate;
            if (dt == null)
            {
                return null;
            }
            return dt;
        }
        public FrameworkElement Child(String name)
        {
            int count = VisualTreeHelper.GetChildrenCount(this.Btn);
            if (count < 1)
            {
                return null;
            }
            for (int i = 0; i < count; i++)
            {
                FrameworkElement ui = VisualTreeHelper.GetChild(this.Btn, i) as FrameworkElement;
                FrameworkElement ui2 = ui.FindName(name) as FrameworkElement;
                if (ui2 != null)
                {
                    return ui2;
                }
            }
            return null;
        }
        public void SetBorderBrush(Color color, ButtonState state = ButtonState.All)
        {
            this.SetBorderBrush(new SolidColorBrush(color), state);
        }
        public void SetBorderBrush(Brush brush, ButtonState state = ButtonState.All)
        {
            this.SetVal(brush, "BorderBrush", state);
        }
        public void SetBackground(Color color, ButtonState state = ButtonState.All)
        {
            this.SetBackground(new SolidColorBrush(color), state);
        }
        public void SetBackground(Brush brush, ButtonState state = ButtonState.All)
        {
            this.SetVal(brush, "Background", state);
        }
        public void SetForeground(Color color, ButtonState state = ButtonState.All)
        {
            this.SetForeground(new SolidColorBrush(color), state);
        }
        public void SetForeground(Brush brush, ButtonState state = ButtonState.All)
        {
            this.SetVal(brush, "Foreground", state);
        }
        public void SetVal(String target, ResourceDictionary rd)
        {
            Dictionary<String, Object> dicts;
            if (!this.StateBrushs.TryGetValue(target, out dicts))
            {
                dicts = new Dictionary<String, Object>();
            }
            foreach (String k in rd.Keys)
            {
                dicts[k] = rd[k];
            }
            this.StateBrushs[target] = dicts;
            this.UpdateState(this.CurrentState);
        }
        public void SetVal(Object val, String target, ButtonState state = ButtonState.All)
        {
            Dictionary<String, Object> dicts;
            if (!this.StateBrushs.TryGetValue(target, out dicts))
            {
                dicts = new Dictionary<String, Object>();
            }
            dicts[state.ToString()] = val;
            this.StateBrushs[target] = dicts;
            this.UpdateState(this.CurrentState);
        }
        private Dictionary<String, Dictionary<String, Object>> StateBrushs = new Dictionary<string, Dictionary<string, Object>>();
        private void UpdateState(String name)
        {
            if (name == null)
            {
                return;
            }
            Object val;
            Dictionary<String, Object> dicts;
            const String ALL_NAME = "All";
            if (this.StateBrushs.TryGetValue("Background", out dicts))
            {
                if (dicts.ContainsKey(name))
                {
                    val = dicts[name];
                    this.Background = val as Brush;
                }
                else if (dicts.ContainsKey(ALL_NAME))
                {
                    val = dicts[ALL_NAME];
                    this.Background = val as Brush;
                }
            }
            if (this.StateBrushs.TryGetValue("Foreground", out dicts))
            {
                if (dicts.ContainsKey(name))
                {
                    val = dicts[name];
                    this.Foreground = val as Brush;
                }
                else if (dicts.ContainsKey(ALL_NAME))
                {
                    val = dicts[ALL_NAME];
                    this.Foreground = val as Brush;
                }
            }
            if (this.StateBrushs.TryGetValue("BorderBrush", out dicts))
            {
                if (dicts.ContainsKey(name))
                {
                    val = dicts[name];
                    this.BorderBrush = val as Brush;
                }
                else if (dicts.ContainsKey(ALL_NAME))
                {
                    val = dicts[ALL_NAME];
                    this.BorderBrush = val as Brush;
                }
            }
            if (this.StateBrushs.TryGetValue("BorderThickness", out dicts))
            {
                if (dicts.ContainsKey(name))
                {
                    val = dicts[name];
                    ExtThickness et = val as ExtThickness;
                    if (et != null)
                    {
                        this.BorderThickness = et.BorderThickness;
                    }
                }
                else if (dicts.ContainsKey(ALL_NAME))
                {
                    val = dicts[ALL_NAME];
                    ExtThickness et = val as ExtThickness;
                    if (et != null)
                    {
                        this.BorderThickness = et.BorderThickness;
                    }
                }
            }
            if (this.StateBrushs.TryGetValue("Title", out dicts))
            {
                if (dicts.ContainsKey(name))
                {
                    val = dicts[name];
                    this.Title = (String)val;
                }
                else if (dicts.ContainsKey(ALL_NAME))
                {
                    val = dicts[ALL_NAME];
                    this.Title = (String)val;
                }
            }
        }
        private String CurrentState;
        private void OnCurrentStateChanged(object sender, VisualStateChangedEventArgs e)
        {
            this.CurrentState = e.NewState.Name;
            this.UpdateState(e.NewState.Name);
        }
        #region ExtButton Properties.
        private Border _BBorder = null;
        public Border BBorder
        {
            get
            {
                return this._BBorder;
            }
        }
        public Button Button
        {
            get
            {
                return this.Btn;
            }
        }
        private Uri _StyleSource = null;
        private ResourceDictionary _ResSet = new ResourceDictionary();
        public ResourceDictionary ResSet
        {
            get
            {
                return _ResSet;
            }
        }
        public event RoutedEventHandler Click
        {
            add
            {
                this.Btn.Click += value;
            }
            remove
            {
                this.Btn.Click -= value;
            }
        }
        private String _StyleName;
        public String StyleName
        {
            get
            {
                return this._StyleName;
            }
            set
            {
                this._StyleName = value;
            }
        }
        private String _TempPath;
        public String TempPath
        {
            get
            {
                return this._TempPath;
            }
            set
            {
                this._TempPath = value;
            }
        }
        public Uri ResSource
        {
            get
            {
                return this._StyleSource;
            }
            set
            {
                this._StyleSource = value;
                this.ResSet.Source = this.ResSource;
                this.SetStyle("Default");
            }
        }
        //
        public static readonly DependencyProperty ContentTemplateProperty = PropertyRegister.Register("ContentTemplate", typeof(DataTemplate), typeof(ExtButton), new PropertyMetadata(null));
        public DataTemplate ContentTemplate
        {
            get
            {
                return this.GetValue(ExtButton.ContentTemplateProperty) as DataTemplate;
            }
            set
            {
                this.SetValue(ExtButton.ContentTemplateProperty, value);
            }
        }
        public static readonly DependencyProperty TitleProperty = PropertyRegister.Register("Title", typeof(String), typeof(ExtButton), new PropertyMetadata(""));
        public String Title
        {
            get
            {
                return this.GetValue(ExtButton.TitleProperty) as String;
            }
            set
            {
                this.SetValue(ExtButton.TitleProperty, value);
            }
        }
        #endregion
    }
}
